(provide nucleoAiris)

(require funcionesAeris asesorAiris/funciones.clp)

(deftemplate portatil
    "plantilla para portatiles"
    (declare (slot-specific TRUE))					;; con slot-specific evitamos refracion
    (slot marca (type STRING))						;; nombre de la marca (AIRIS)
    (slot modelo (type STRING)) 					;; nombre del modelo de portatil
    (slot precio (type INTEGER)) 					;; en euros
    (slot tipoPantalla (type STRING))				;; tipo de pantalla
    (slot pulgadas (type FLOAT)) 					;; en pulgadas
    (slot resolucionX (type INTEGER))  				;; en p�xeles
    (slot resolucionY (type INTEGER))  				;; en p�xeles
	(slot procesador (type STRING))			 		;; nombre del procesador
    (slot hilos (type INTEGER))						;; numero de hilos de procesador				 
    (slot reloj (type INTEGER))						;; en mhz
    (slot tipoGrafica (type STRING))				;; tarjeta grafica
    (slot memGrafica (type INTEGER))				;; en megas
    (slot graficaDedicada (type INTEGER))			;; 1 cierto, 0 falso
    (slot memRam (type INTEGER))					;; en megas
    (slot disco (type INTEGER))						;; tama�o de memoria de disco en gigas
    (slot numUsbs (type INTEGER))							
    (slot pixelesWebcam (type FLOAT))				;; en megapixeles
    (multislot tipoWifi)							;; a, b, g, n...
    (slot duracionBateria	(type FLOAT)) 			;; en horas
    (slot peso (type FLOAT))						;; en kilogramos		
    (slot puntuacion (Type INTEGER) (default 0))	;; para ordenar los portatiles aceptables
    (multislot bonosRecibidos)						;; lista de las reglas que lo han bonificado
    (slot link (Type STRING))
)

(deftemplate bonoRam
	"Indica que se han de bonificar los port�tiles con ram de al menos una cantidad dada"
	(slot min (type INTEGER) (default 0))		;;memoria m�nima para recibir el bono
    (slot bono (type INTEGER) (default 0))) 	;;cuanto se han de bonificar. Si negativo => resta
(deftemplate bonoGrafica
	"Indica que se han de bonificar las tarjetas graficas con memoria de al menos una cantidad dada"
	(slot min (type INTEGER) (default 0))		;;memoria m�nima para recibir el bono
    (slot dedicada (type INTEGER) (default 0))  ;;1 si es necesario tener memoria dedicada para bonificar
    (slot bono (type INTEGER) (default 0))) 	;;cuanto se han de bonificar. Si negativo => resta
(deftemplate bonoDisco
    "Indica que se han de bonificar los portatiles con un minimos de capacidad"
    (slot min (type INTEGER) (default 0))		;;capacidad minima para bonificar
    (slot bono (type INTEGER) (default 0)))		;;cuanto se ha de bonificar. Si negativo => resta
(deftemplate bonoPulgadas
    "Indica que se han de bonificar los portatiles con un m�nimo de pulgadas"
    (slot min (type INTEGER) (default 0))		;;pulgadas m�nimas para bonificar
    (slot bono	(type INTEGER) (default 0)))	;;cuanto se ha de bonificar. Si negativo => resta
(deftemplate bonoPeso
    "Indica que se han de bonificar los portatiles con un m�nimo de peso"
    (slot min (type FLOAT) (default 0))			;;kg m�nimo para bonificar
    (slot bono	(type INTEGER) (default 0)))	;;cuanto se ha de bonificar. Si negativo => resta
(deftemplate bonoProcesador
    "Indica que se han de bonificar los portatiles con un procesador m�nimo"
    (slot relojMin (type INTEGER) (default 0))	;;MHz m�nimos para bonificar
    (slot hilosMin (type INTEGER) (default 0))	;;hilos m�nimos para bonificar
    (slot bono	(type INTEGER) (default 0)))	;;cuanto se ha de bonificar. Si negativo => resta
(deftemplate bonoBateria
    "Indica que se han de bonificar los portatiles con una bater�a m�nima"
    (slot intensidadMin (type INTEGER) (default 0))	;;mA m�nimos para bonificar
    (slot horasMin (type INTEGER) (default 0))		;;horas de bater�a m�nimos para bonificar
    (slot bono	(type INTEGER) (default 0)))		;;cuanto se ha de bonificar. Si negativo => resta
(deftemplate bonoWifi
    "Indica que se han de bonificar los portatiles con m�s tipos de wifi"
    (slot bono	(type INTEGER) (default 0)))	;;cuanto se ha de bonificar. Si negativo => resta
(deftemplate bonoResolucion
    (slot bono (type INTEGER) (default 0)))     ;;cuanto se ha de bonificar. Si negativo => resta    

(deftemplate precioBuscado
	"Indica que solo se buscan portatiles dentro de un determinado rango de precio"
	(slot min (type INTEGER) (default 0)) ;;en euros
    (slot max (type INTEGER) (default -1))) ;;en euros. -1 significa indefinido
(deftemplate pulgadasBuscadas
	"Indica que solo se buscan portatiles dentro de un determinado rango de pulgadas"
	(slot min (type INTEGER) (default 0)) 		;;en pulgadas
    (slot max (type INTEGER) (default -1))) 	;;en pulgadas. -1 significa indefinido
(deftemplate resolucionBuscada
	"Indica que solo se buscan portatiles dentro de un determinado rango"
    (slot xMin (type INTEGER) (default 0)) 	;;en p�xeles
    (slot yMin (type INTEGER) (default 0)) 	;;en p�xeles
    (slot xMax (type INTEGER) (default -1)) ;;en p�xeles. -1 significa indefinido
    (slot yMax (type INTEGER) (default -1)));;en p�xeles. -1 significa indefinido
(deftemplate ramBuscada
	"Indica que solo se buscan portatiles con una cantidad de memoria dentro de un rago"
	(slot min (type INTEGER) (default 0)) 		;;en MB
    (slot max (type INTEGER) (default -1))) 	;;en MB. -1 significa indefinido
(deftemplate discoBuscado
	"Indica que solo se buscan portatiles con una cantidad de memoria de disco dentro de un rango"
	(slot min (type INTEGER) (default 0)) 		;;en GB
    (slot max (type INTEGER) (default -1))) 	;;en GB. -1 significa indefinido
(deftemplate pesoBuscado
	"Indica que solo se buscan portatiles con una cantidad de memoria de disco dentro de un rango"
	(slot min (type INTEGER) (default 0)) 		;;en Kg
    (slot max (type INTEGER) (default (get-member java.lang.Integer MAX_VALUE)))) 	;;en Kg. -1 significa indefinido
(deftemplate graficaBuscada
	"Indica que solo se buscan portatiles con una cantidad de memoria grafica dentro de un rango o con memoria dedicada"
	(slot min (type INTEGER) (default 0)) 		;;en MB
    (slot max (type INTEGER) (default -1))  	;;en MB. -1 significa indefinido
    (slot dedicada (type INTEGER) (default 0))) ;;1 significa que solo se buscan dedicadas
(deftemplate bateriaMin
    "Indica que solo se quieren portatiles cuya bater�a dure m�s que un m�nimo"
    (slot tiempo 		(type FLOAT) (default 0))) ;;en horas
(deftemplate procesadorMin
    "Indica que solo se quieren port�tiles que cumplan unos requisitos de procesador"
    (slot reloj (type INTEGER) (default 0)) ;; velocidad m�nima en Mhz
    (slot hilos (type INTEGER) (default 0))) ;;n�mero m�nimo de hilos

(defrule filtrarPrecio
	"Elimina de la memoria aquellos port�tiles cuyo precio salga del rango establecido"
    (precioBuscado (min ?min) (max ?max))
    ?portatil <- (portatil (precio ?precio))
    (test (fueraDeRango ?precio ?max ?min))
	=>
    (retract ?portatil))
(defrule filtrarPulgadas
	"Elimina de la memoria aquellos port�tiles cuyas pulgadas salgan del rango establecido"
    (pulgadasBuscadas (min ?min) (max ?max) )
    ?portatil <- (portatil (pulgadas ?pulgadas))
    (test (fueraDeRango ?pulgadas ?max ?min))
	=>
    (retract ?portatil)
)
(defrule filtrarResolucion
	"Elimina de la memoria aquellos port�tiles cuya resolucion est� fuera del rango establecido"
    (resolucionBuscada (xMin ?minX) (yMin ?minY) (xMax ?maxX) (yMax ?maxY))
    ?portatil <- (portatil (resolucionX ?resX) (resolucionY ?resY))
    (or
        (test (fueraDeRango ?resX ?maxX ?minY))
    	(test (fueraDeRango ?resY ?maxY ?minY))
    )
	=>
    (retract ?portatil)
    )
(defrule filtrarRam
	"Elimina de la memoria aquellos port�tiles cuya memoria ram est� fuera del rango establecido"
    (ramBuscada (min ?min) (max ?max))
    ?portatil <- (portatil (memRam ?ram))
    (test (fueraDeRango ?ram ?max ?min))
    =>
    (retract ?portatil)
    )

(defrule filtrarDisco
	"Elimina de la memoria aquellos port�tiles cuya memoria de disco est� fuera del rango establecido"
    (discoBuscado (max ?max) (min ?min))
    ?portatil <- (portatil (disco ?disco))
    (test (fueraDeRango ?disco ?max ?min))
	=>
    (retract ?portatil))
(defrule filtrarGrafica
	"Elimina de la memoria aquellos port�tiles cuya tarjeta gr�fica no cumpla los requisitos"
    (graficaBuscada (min ?min) (max ?max) (dedicada ?buscoDedicada))
    ?portatil <- (portatil (memGrafica ?mem) (graficaDedicada ?dedicada))
    (or
        (test (fueraDeRango ?mem ?max ?min))
    	(test (neq ?buscoDedicada ?dedicada))
    )
	=>
    (retract ?portatil)
    )
(defrule filtrarBateria
	"Elimina de la memoria aquellos port�tiles cuya bater�a no cumpla los requisitos"
    (bateriaMin (tiempo ?tiempoMin))
    ?portatil <- (portatil (duracionBateria ?tiempo))
	(test (fueraDeRango ?tiempo (get-member java.lang.Integer MAX_VALUE) ?tiempoMin))
	=>
    (retract ?portatil))
(defrule filtrarPeso
	"Elimina de la memoria aquellos port�tiles cuya memoria de disco est� fuera del rango establecido"
    (pesoBuscado (max ?max) (min ?min))
    ?portatil <- (portatil (peso ?peso))
    (test (fueraDeRango ?peso ?max ?min))
	=>
    (retract ?portatil))
(defrule filtrarProcesadores
    "Elimina de la memoria aquellos port�tiles cuyo procesador no cumpla los requisitos"
    (procesadorMin (reloj ?relojMin) (hilos ?hilosMin))
    ?portatil <- (portatil (hilos ?hilos) (reloj ?reloj))
    (or
            (test (fueraDeRango ?hilos (get-member java.lang.Integer MAX_VALUE) ?hilosMin ))
    		(test (fueraDeRango ?reloj (get-member java.lang.Integer MAX_VALUE) ?relojMin ))
    )
    =>
    (retract ?portatil)
    )

(defrule bonificarRam
    "Se encarga de bonificar los port�tiles con una cantidad m�nima de memoria ram"
    ?bono <- (bonoRam (min ?min) (bono ?bono))
    ?portatil <- (portatil (memRam ?mem) (puntuacion ?puntuacion) (bonosRecibidos $?bonos))
    (not (test (member$ bonificarRam ?bonos)))
    (test (>= ?mem ?min))
    =>
    (modify ?portatil (puntuacion (+ ?puntuacion ?bono)) (bonosRecibidos ?bonos bonificarRam))
    )
(defrule bonificarGrafica
    "Se encarga de bonificar los port�tiles con cierto tipo de tarjetas gr�ficas"
    ?bono <- (bonoGrafica (min ?memMin) (dedicada ?dedicadaMin) (bono ?bono))
    ?portatil <- (portatil (memGrafica ?mem) (graficaDedicada ?dedicada) (puntuacion ?puntuacion) (bonosRecibidos $?bonos))
    (not (test (member$ bonificarGrafica ?bonos)))
    (test (>= ?mem ?memMin))
    (test (>= ?dedicada ?dedicadaMin))
    =>
    (modify ?portatil (puntuacion (+ ?puntuacion ?bono)) (bonosRecibidos ?bonos bonificarGrafica))
    )
(defrule bonificarDisco
    "Se encarga de bonificar los port�tiles con cierta capacidad de disco duro"
    ?bono <- (bonoDisco (min ?disMin) (bono ?bono))
    ?portatil <- (portatil (disco ?mem) (puntuacion ?puntuacion) (bonosRecibidos $?bonos))
    (not (test (member$ bonificarDisco ?bonos)))
    (test (>= ?mem ?disMin))
    =>
    (modify ?portatil (puntuacion (+ ?puntuacion ?bono))(bonosRecibidos ?bonos bonificarDisco))
    )
(defrule bonificarPulgadas
    "Se encarga de bonificar los port�tiles con una cantidad m�nima de pulgadas"
    (bonoPulgadas (min ?min) (bono ?bono))
    ?portatil <- (portatil (pulgadas ?pulgadas) (puntuacion ?puntuacion) (bonosRecibidos $?bonos))
    (not (test (member$ bonificarPulgadas ?bonos)))
    (test (>= ?pulgadas ?min))
    =>
    (modify ?portatil (puntuacion (+ ?puntuacion ?bono))(bonosRecibidos ?bonos bonificarPulgadas))
    )
(defrule bonificarPeso
    "Se encarga de bonificar los port�tiles con una cantidad m�nima de peso"
    ?bono <- (bonoPeso (min ?min) (bono ?bono))
    ?portatil <- (portatil (peso ?peso) (puntuacion ?puntuacion) (bonosRecibidos $?bonos))
    (not (test (member$ bonificarPeso ?bonos)))
    (test (>= ?peso ?min))
    =>
    (modify ?portatil (puntuacion (+ ?puntuacion ?bono))(bonosRecibidos ?bonos bonificarPeso))
    )
(defrule bonificarProcesador
    "Se encarga de bonificar los port�tiles con unas ciertas caracter�sticas m�nimas"
    ?bono <- (bonoProcesador (relojMin ?relojMin) (hilosMin ?hilosMin) (bono ?bono))
    ?portatil <- (portatil (reloj ?reloj) (hilos ?hilos) (puntuacion ?puntuacion) (bonosRecibidos $?bonos))
    (not (test (member$ bonificarProcesador ?bonos)))
    (test (>= ?hilos ?hilosMin))
    (test (>= ?reloj ?relojMin))
    =>
    (modify ?portatil (puntuacion (+ ?puntuacion ?bono))(bonosRecibidos ?bonos bonificarProcesador))
    )
(defrule bonificarBateria
    "Se encarga de bonificar los port�tiles con unas caracter�sticas m�nimas de bater�a"
    ?bono <- (bonoBateria (horasMin ?hMin) (bono ?bono) )
    ?portatil <- (portatil (duracionBateria ?h) (puntuacion ?puntuacion) (bonosRecibidos $?bonos))
    (not (test (member$ bonificarBateria ?bonos)))
    (test (>= ?h ?hMin))
    =>
    (modify ?portatil (puntuacion (+ ?puntuacion ?bono))(bonosRecibidos ?bonos bonificarBateria))
    )
(defrule bonificarWifi
    "Se encarga de bonificar los port�tiles que soportan un mayor n�mero de tecnolog�as wifi"
    ?bono <- (bonoWifi (bono ?bono))
    ?portatil <- (portatil (tipoWifi ?w) (puntuacion ?puntuacion) (bonosRecibidos $?bonos))
    (not (test (member$ bonificarWifi ?bonos)))
    =>
    (modify ?portatil (puntuacion (+ ?puntuacion (* ?bono (length$ ?w))))(bonosRecibidos ?bonos bonificarWifi))
    )
(defrule bonificarResolucion
    "Se encarga de bonificar los port�tiles que mejor resolucion tienen"
    ?bono <- (bonoResolucion (bono ?bono))
    ?portatil <- (portatil (puntuacion ?puntuacion) (bonosRecibidos $?bonos))
    (not (test (member$ bonificarResolucion ?bonos)))
    =>
    (modify ?portatil (puntuacion (+ ?puntuacion ?bono))(bonosRecibidos ?bonos bonificarResolucion))
    )




